package org.slf4j.impl;

import com.acme.javaschool.intense.sems.sem3logging.*;
import org.slf4j.ILoggerFactory;

import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

public class YetAnotherLoggerFactory implements ILoggerFactory {

    private static final String CONFIG_FILE_KEY = "logger.properties";
    private static final Map<String, Level> stringToLevelMapping;

    private static final ConcurrentMap<String, YetAnotherLoggerAdapter> loggers = new ConcurrentHashMap<>();
    private static Level defaultLevel = Level.INFO;
    private static String defaultAppender = "Console";
    private static int bufferSize = 100;
    private static String fileName = "soVeryCustomUniqueLogFileName.txt";

    static {
        stringToLevelMapping = new HashMap<>();
        stringToLevelMapping.put("OFF", Level.OFF);
        stringToLevelMapping.put("DEBUG", Level.DEBUG);
        stringToLevelMapping.put("INFO", Level.INFO);
        stringToLevelMapping.put("ERROR", Level.ERROR);

        try {
            initConfig();
        } catch (IOException e) {
            System.out.println("Init failed: properties file not found.");
        }
    }

    public static void initConfig() throws IOException {

        Properties systemProperties = System.getProperties();
        Properties properties = new Properties();
        if (!systemProperties.containsKey(CONFIG_FILE_KEY)) {
            System.out.println("Please specify VM key -Dlogger.properties=<file_name>");
            return;
        }
        properties.load(new FileReader(systemProperties.getProperty(CONFIG_FILE_KEY)));

        defaultLevel = stringToLevelMapping.get(properties.getProperty("defaultLevel"));
        defaultAppender = properties.getProperty("defaultAppender");
        bufferSize = Integer.valueOf(properties.getProperty("bufferSize"));

        if (defaultAppender.equals("File")) {
            fileName = properties.getProperty("fileName");
        }
    }

    @Override
    public YetAnotherLoggerAdapter getLogger(String name) {
        if (!loggers.containsKey(name)) {
            YetAnotherLogger logger = new YetAnotherLogger(name, defaultLevel);

            switch (defaultAppender) {
                case "Console":
                    if (logger.appenderIsInit(AppenderType.CONSOLE)) {
                        logger.addAppender(AppenderType.CONSOLE);
                    } else {
                        logger.addAppender(new ConsoleAppender(bufferSize));
                    }
                    break;
                case "File":
                    if (logger.appenderIsInit(AppenderType.FILE)) {
                        logger.addAppender(AppenderType.FILE);
                    } else {
                        try {
                            logger.addAppender(new FileAppender(bufferSize, fileName));
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    break;
                default:
                    throw new IllegalArgumentException("UNKNOWN APPENDER SPECIFIED");
            }
            loggers.putIfAbsent(name, new YetAnotherLoggerAdapter(logger));
        }
        return loggers.get(name);
    }
}
